数组
数组为什么特殊?
- 效率:就是一个简单的线性序列,因此访问速度很快。但是代价是空间被限制。ArrayList空间的自动分配是将旧实例中所有的引用移到新实例中,但是这种弹性需要额外的开销。
- 类型:在泛型出现之前,容器中的所有对象都当作根对象Object处理,而数组可以定义具体类型(这种数组成为对象数组),以通过编译器检查,防止插入错误类型和抽取不当类型。
- 数组可以持有基本类型:容器只能持有对象,当然,现在的JAVA具有了自动包装机制,让容器看起来也持有基本类型。
数组和容器的差别在哪?
在于数组使用[]来访问,容器使用set(),get()。
随着泛型和自动包装的出现,数组仅有的优势在于效率,但是这种效率的提升并不能代替容器带来的简便,因此还是推荐使用容器。
数组是一个对象吗?
是的,只是这个对象很特殊,我们找不到他的CLASS文件,因为他是由底层JAVA虚拟机来生成的,因此数组也是Object的子类,但是会特别对待,具体的知识了解JVM后才能弄明白。
对象数组中保存其他对象的引用。
基本类型数组保存值。
数组重写了Object类里的toString()方法吗?
没有,那要怎么输出数组中的值?而不是打印这个对象引用呢?
使用Arrays.toString(a)。
多维数组使用Arrays.deepToString(a)
JAVA中的数组和C,C++中数组有区别吗?
有,回忆在C,C++中调用函数返回一个数组的例子?我们只能返回一个数组的指针(意味着只能通过这个指针去访问数组元素),但是这么做的话会使这个数组的生命周期变得很复杂,内存无法回收,而且导致内存泄漏,而在JAVA中,我可以直接返回一个“数组”,剩下的一切交给垃圾回收器处理。
1 | public static A[] f(){return ...}; |
数组和泛型为什么不能很好的结合?
1 | Peel<Banana>[] peels = new Peel<Banana> [10]; // Illegal |
泛型的擦除会擦除参数类型信息,使得所有的参数类型都是Object,而数组并不满足于此,它需要明确的知道具体的参数类型是什么,所以产生了矛盾。
但是我们可以在泛型类或者泛型方法中使用参数化的数组。
但是可以这样处理:1
2Peel<Banana>[] peels;
peels = (new Peel<Banana>) Object[10]; // Illegal
如何理解
有一个说法是,JAVA语法规范中说明:
数组是协变性的,具象性的,泛型时无关性的。
如何快速的填充数组中的数据以用于各种测试?
- 使用Arrays中的fill()方法,但是有一个局限,就是只能用同一个值(引用)填充数组。
- 使用Generator自定义一套生成的方式。
Arrays实用功能
- arraycopy(source,splace,title,tpalce,length)复制
- equals(a1,a2),个数,每个元素equal()。
- deepEquals():多位数组比较
- sort():排序,排序的规则或者实现Comparable,要么传递一个Comparator类。